package cn.sys.controller;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.sys.controller.dto.DormitoryInfoDTO;
import cn.sys.controller.dto.MaintainDormitorySearchDTO;
import cn.sys.controller.dto.SearchDTO;
import cn.sys.dao.DormitoryDao;
import cn.sys.dao.MaintainDormitoryDao;
import cn.sys.dao.NoticeDao;
import cn.sys.entity.MaintainDormitory;
import cn.sys.entity.Notice;
import cn.sys.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Before;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

public class Test {
    DormitoryDao dormitoryDao = null;
    MaintainDormitoryDao maintainDormitoryDao = null;
    NoticeDao noticeDao = null;
    @Before
    public void init(){
        SqlSession sqlSession = MybatisUtil.getSQLSession();
        dormitoryDao = sqlSession.getMapper(DormitoryDao.class);
        maintainDormitoryDao = sqlSession.getMapper(MaintainDormitoryDao.class);
        noticeDao = sqlSession.getMapper(NoticeDao.class);

    }

    @org.junit.Test
    public void myTest01(){
        DormitoryInfoDTO dormitoryInfoDTO = dormitoryDao.findDormitoryByStuId(1);
        int i = dormitoryDao.findDormitoryCountByDorId(dormitoryInfoDTO.getDorId());
        System.out.println(dormitoryInfoDTO);
        System.out.println(i);
    }

    @org.junit.Test
    public void myTest02(){
        List<Map<String, Object>> list = dormitoryDao.findDormitoryTotal();
        System.out.println(list.get(0).get("bedTotal"));
    }

    @org.junit.Test
    public void myTest03(){
        MaintainDormitorySearchDTO searchDTO = new MaintainDormitorySearchDTO();
        searchDTO.setState(0);
        searchDTO.setPageSize(5);
        searchDTO.setPageNum(1);
        List<Map<String, Object>> list = maintainDormitoryDao.findMaintainDormitoryAndPositionByState(searchDTO);
        System.out.println(list);
    }

    @org.junit.Test
    public void myTest04() throws IOException {
        InputStream is = new FileInputStream("D:\\MyStudy_22\\EducationBase\\JavaEE\\Work\\StudentSysManager\\src\\user.xls");
        ExcelReader excelReader = ExcelUtil.getReader(is);
        List<Map<String, Object>> maps = excelReader.readAll();
        for (Map<String, Object> map : maps){
            System.out.println(map);
        }

    }

    /**
     * 将一个map中的数据封装到一个任意类的属性中，只要指定类的属性名和map中的key一致，就把map中对应key的值复制给该属性。
     * @param param 参数数据
     * @param aClass    任意的类，将属性赋给类的对象
     */
    private Object getBean(Map<String, Object> param, Class aClass){
        // obj是最终需要的对象，将map中的数据封装到obj中
        Object obj = null;
        try {
            obj = aClass.getConstructor().newInstance();
            // 获取当前类的属性数组，转为集合，方便判断
            Field[] fields = aClass.getFields();
            Set<String> keys = param.keySet();
            for (String key : keys) {
                // map中的key就是属性名，但实际上类中可能不存在该属性，就会抛出异常，所以需要先判断。
                if(!existField(fields, key)) {
                    continue;
                }
                Field field = aClass.getDeclaredField(key);
                field.setAccessible(true);
                field.set(obj, param.get(key));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    // 判断属性是否在类中存在
    private boolean existField(Field[] fields, String key){
        for (int i = 0; i < fields.length; i++) {
            if(fields[i].getName().equals(key)){
                return true;
            }
        }
        return false;
    }

    @org.junit.Test
    public void myTest05() {
        Map<String, Object> map = new HashMap<>();
        map.put("username", "张三");
        map.put("password", "123");
        map.put("age", 20);
        map.put("address", "四川");

        //需求： 将map中的数据封装到User类中（利用反射：允许程序运行起来以后，对任何一个未知类做操作，即获取方法、调用属性、调用方法等）
        // 定义一个工具类，可以将map中的数据封装到任意类型的对象（未知的对象）中
        Object obj = getBean(map, User.class);
        System.out.println(obj);


        /*
        反射：
            Class是存放类信息的类，即Java中的任意一个类都是一个Class对象。
                加载一个类，实际上程序中new Class();来存放该类的信息。
                （注意Class的构造是私有的，不能自己调用，只能使用内部提供的。因为随便使用就无法判断表示哪个类，
                进而引出了三个获取的方法：Class.forName("cn.test.User")、User.class、user.getClass()。）
            获取到了对应的类，就能获取到属性和方法。对属性就是赋值和取出，对方法就是调用。
            获取到类，可以创建类的对象（通过Class对象获取构造器，创建对象），通过这个对象对属性赋值
                （Field对象表示了具体哪个属性，对其赋值还需指定哪个对象，对哪个对象进行赋值；调用方法也是同理）。
         */
        /*try {
            Class userClass = Class.forName("cn.sys.controller.User");
            Field username = userClass.getDeclaredField("username");
            username.setAccessible(true);
            // 注意在获取属性和方法的时候，直接getField不能获取私有属性，需要使用getDeclaredField，如果要设置其值，还要设置setAccessible为true。方法也是同理。
            Method getUsername = userClass.getMethod("getUsername");
            Method setUsername = userClass.getMethod("setUsername", String.class);

            Constructor constructor = userClass.getConstructor();
            Object obj = constructor.newInstance();

            username.set(obj, "张三");

        } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }*/


    }

    @org.junit.Test
    public void myTest07(){
        Notice notice = new Notice();
        notice.setManagerId(2);
        notice.setCreateTime(new Date());
        notice.setContent("测试两下");
        notice.setType(1);
        int i = noticeDao.addNotice(notice);
        System.out.println(notice.getId());
    }
}

class User{
    private String username;
    private String password;
    private Integer age;
    private String address;

    public User() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

class Student{

}
